package com.mach.platform.service;

import com.google.common.collect.Ordering;
import com.mach.platform.domain.BaseCode;
import com.mach.platform.domain.iot.IotDevType;
import com.mach.platform.innotation.DelCache;
import com.mach.platform.repository.BaseCodeRepo;
import com.mach.platform.repository.IotDevTypeRepo;
import com.mach.platform.utils.springdata.DynamicSpecifications;
import com.mach.platform.utils.springdata.SearchFilter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;

import javax.transaction.Transactional;
import java.util.*;
import java.util.Map.Entry;
import java.util.stream.Collectors;

/**
 * @author Anonymous
 * @Description: 设备库 服务类
 * @Package: com.mach.platform.service
 * @time 2018/04/27 23:11
 */
@Slf4j
@Service
public class IotDevTypeServiceImpl implements BaseService<IotDevType> {

	@Autowired
	private IotDevTypeRepo deviceTypeRepo;

	@Autowired
	private BaseCodeRepo baseCodeRepo;

	/**
	 * 保存
	 *
	 * @param device 保存的实体
	 * @return T 返回保存后的实体
	 */
	@Transactional(rollbackOn = Exception.class)
	@Override
	public IotDevType save (IotDevType device) {

		IotDevType dbResult = deviceTypeRepo.saveAndFlush(device);

		return dbResult;
	}

	/**
	 * 插入，批量保存
	 *
	 * @param list 实体集合
	 * @return List<T>
	 */
	@Override
	public List<IotDevType> insertObjInBatch (List<IotDevType> list) {
		return null;
	}

	/**
	 * 更新
	 *
	 * @param device 跟新的实体
	 * @return T
	 */
	@Transactional(rollbackOn = Exception.class)
	@DelCache
	@Override
	public IotDevType update (IotDevType device) {

		IotDevType dbResult = deviceTypeRepo.saveAndFlush(device);

		return dbResult;
	}

	/**
	 * 删除--批量删除
	 *
	 * @param ids 批量删除id
	 * @return int 影响数
	 */
	@Transactional(rollbackOn = Exception.class)
	@Override
	public int delete (Long[] ids) {
		return deviceTypeRepo.deleteByIdIn(ids);
	}

	/**
	 * 获取列表数据---使用 com.mach.platform.utils.springdata  下的DynamicSpecifications 的
	 * 写法进行分页查询
	 *
	 * @param pageable 分页参数
	 * @param params   其他参数
	 * @return Page<T>
	 */
	@Override
	public Page<IotDevType> list (Pageable pageable, Map params) {

		Specification specification = DynamicSpecifications
				                              .bySearchFilter(SearchFilter.parse(params).values(), IotDevType.class);

		return deviceTypeRepo.findAll(specification, pageable);
	}

	/**
	 * 获取单体 数据
	 *
	 * @param id 获取详情的id
	 * @return T
	 */
	@Override
	public IotDevType info (Long id) {
		return deviceTypeRepo.getOne(id);
	}

	/**
	 * 获取 设备类型 的图标配置 上传图片数据
	 * @return
	 */
	public Map getIconDeviceOptions ( ) {

		List<IotDevType> dbResult = deviceTypeRepo.findAll();

		if (dbResult.size()>0){

			Map<String, List<IotDevType>> stringListMap = dbResult.stream().collect(Collectors.groupingBy(IotDevType::getUseType));

			// 获取 数据的排列次序
			List<BaseCode> results = baseCodeRepo.findAllByGroupTypeOrderBySortAsc(1003);

			if (results.size() > 0) {

				// 进行排序
				Map<String, List<IotDevType>> finalMapGroup = stringListMap.entrySet().stream().sorted(new Comparator<Entry<String, List<IotDevType>>>() {

					List<String> standarList = results.stream().map(Item -> Item.getName())
					                                  .collect(Collectors.toList());
					Ordering ordering = Ordering.explicit(standarList);

					@Override
					public int compare (Entry<String, List<IotDevType>> o1, Entry<String, List<IotDevType>> o2) {

						if (standarList.contains(o1.getKey()) && standarList.contains(o2.getKey())) {

							return ordering.nullsFirst().compare(o1.getKey(), o2.getKey());
						} else {
							return 0;
						}
					}
				}).collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (oldValue, newValue) -> oldValue,
						LinkedHashMap::new));

				return finalMapGroup;
			}

			return stringListMap;

		} else {
			return Collections.emptyMap();
		}

	}

	/**
	 * 保存上传图片的 信息到数据库
	 *
	 * @param id
	 * @param picUrl
	 */
	@Transactional(rollbackOn = Exception.class)
	public void uploadPic (Long id, String picUrl) {
		deviceTypeRepo.updateIconUrl(id, picUrl);
	}
}
